package com.ttbj.product.yitong.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.ttbj.api.dto.CutPayData;
import com.ttbj.api.dto.QueryVO;
import com.ttbj.api.yitong.YTFinancialService;
import com.ttbj.core.util.DateUtils;
import com.ttbj.core.util.JsonTools;
import com.ttbj.core.util.JsonUtil;
import com.ttbj.product.util.HttpUtils;
import com.ttbj.product.util.PropertiesUtil;
import com.ttbj.product.ytpayutil.RandomCharData;
import com.ttbj.product.ytpayutil.UtilAes;
import com.ttbj.product.ytpayutil.UtilBase64;
import com.ttbj.product.ytpayutil.UtilRsa;


@Service("ytFinancialService")
public class YTFinancialServiceImpl implements YTFinancialService{
	
	private static final Logger logger = LoggerFactory.getLogger(YTFinancialServiceImpl.class);
	
	private static String STATUS = "status";	//表示状态
	private static String DATA = "data";	//表示返回的数据
	
	@Override
	public Map<String, String> getYTFinancialResult(Object data, int length, String serviceInterface) throws Exception{
		//获取 QueryVo对象
		QueryVO query = getQueryVo(data, length, serviceInterface);
		//将传入的对象转成json格式，accData属性为data节点
		String reqJson = JsonTools.GsonString(query);
		logger.info("对象转成json是-->{}", reqJson);
		//获取reqResult
		String reqResult = getReqResult(reqJson, length, serviceInterface);
		String code = reqResult.split("\\|")[0];
		Map<String, String> resultMap = new HashMap<>();
		if("1".equals(code)) {	//如果code为1，则说明正常返回
			String aesJsonStr = reqResult.split("\\|")[1];
			//AES密钥
			String aesKey = PropertiesUtil.getInstance().getValue("client_aes_key");
			//使用AES进行解密
			aesJsonStr = UtilAes.AES_Decrypt(aesKey, aesJsonStr);
			resultMap.put(STATUS, "1");
			resultMap.put(DATA, aesJsonStr);
			logger.info("YTFinancialServiceImpl返回json是-->{}", aesJsonStr);
		}else if ("0".equals(code)) {	//如果code为0，则说明错误
			resultMap.put(STATUS, "0");
			resultMap.put("reqTime", query.getReqTime());	//获取请求的时间
			resultMap.put(DATA, reqResult);
		}
		return resultMap;
	}

	@Override
	public Map<String, String> getCutPayResult(String paymentOrderNo, List<Object> datas, int length, String serviceInterface) throws Exception{
		if (datas == null || datas.size() == 0 || datas.size() > 10) {
			throw new Exception("分账中的数据不能为空或最多10条数据");
		}
		//初始化分账参数
		CutPayData cutPayData = new CutPayData(paymentOrderNo, datas);
		//获取 QueryVo对象
		QueryVO query = getQueryVo(cutPayData, length, serviceInterface);
		//将传入的对象转成json格式，cutData属性为data节点
		String reqJson = JsonTools.GsonString(query);
		logger.info("对象转成json是-->{}", reqJson);
		//获取reqResult
		String reqResult = getReqResult(reqJson, length, serviceInterface);
		String code = reqResult.split("\\|")[0];
		Map<String, String> resultMap = new HashMap<>();
		if("1".equals(code)) {
			String aesJsonStr = reqResult.split("\\|")[1];
			//AES密钥
			String aesKey = PropertiesUtil.getInstance().getValue("client_aes_key");
			//使用AES进行解密
			aesJsonStr = UtilAes.AES_Decrypt(aesKey, aesJsonStr);
			resultMap.put(STATUS, "1");
			resultMap.put(DATA, aesJsonStr);
			logger.info("返回json是-->{}", aesJsonStr);
		}else if ("0".equals(code)) {	//如果返回了失败，返回应答码，应答信息，以及请求的json数据用于再次请求分账
			resultMap.put(STATUS, "0");
			resultMap.put(DATA, reqResult);
			resultMap.put("reqJson", JsonUtil.getJsonStrByNode(reqJson, "data"));
		}
		return resultMap;
	}
	
	@Override
	public Map<String, String> getWdNotify(String noticeStr) throws Exception {
		//从body中获取回调通知报文
//		String noticeStr = readAsChars(request);
		String client_rsa_privatekey = PropertiesUtil.getInstance().getValue("client_rsa_privatekey");
		String platform_rsa_publickey = PropertiesUtil.getInstance().getValue("platform_rsa_publickey");
        String[] arr = noticeStr.split("\\|");
        //第一段：暂时不需要
        String tag = arr[0];
        //第二段：用rsa私钥解密出 AES秘钥key
        String aesKey = new String(UtilRsa.decryptByPrivateKey(UtilBase64.decode(arr[1]), client_rsa_privatekey));
        //第三段：使用AES秘钥解密报文体
        String json = UtilAes.AES_Decrypt(aesKey, new String(UtilBase64.decode(arr[2])));//注意：这边base64解码两次
        //第四段：使用平台公钥验证签名
        boolean checkAutograph = UtilRsa.verify(json.getBytes("UTF-8"), platform_rsa_publickey, new String(UtilBase64.decode(arr[3])));//注意：这边base64解码两次
        Map<String, String> map = new HashMap<>();
        //如果签证验证失败，则返回0，成功返回1
        if(!checkAutograph){
            map.put(STATUS, "0");
        }else{	//签证是为了防止篡改，签证失败，STATUS(00)可能是被别人篡改的，所以先验证签证是否成功，再判断STATUS状态值
        	map.put(STATUS, "1");
        }
        map.put(DATA, json);
        logger.info("提现回调中，解密后的数据为：{}", json);
        return map;
	}
	
	/**
	 * 获取封装的 QueryVo 对象
	 * @param data 账户开户 账户变更  查询 使用的类
	 * @param length 需要多少位纯数字随机数
	 * @param serviceInterface 易通金服接口名：简写
	 * @param paymentOrderNo 支付订单号
	 * @param objects 分账需要请求的数据，是一个List<Object>类型
	 * @return
	 */
	private QueryVO getQueryVo(Object data, int length, String serviceInterface) {
		//设置版本
		String version = PropertiesUtil.getInstance().getValue("version");
		//设置机构代码
		String instiCode = PropertiesUtil.getInstance().getValue("instiCode");
		//设置请求时间格式：YYYYMMDDhhmmss
		String reqTime = DateUtils.getDateTimeStr(new Date());
		//设置流水号
		String trcNo = RandomCharData.createData(length);
		//设置交易类型如： OPEN_ACC,CUTPAY
		String trxType = serviceInterface.toUpperCase();
		QueryVO query = new QueryVO(version, instiCode, reqTime, trxType, trcNo, data);
		return query;
	}
	
	
	/**
	 * 对数据进行加密并获取请求易通金服接口返回的数据
	 * @param reqJson 请求参数的json数据
	 * @param length 需要多少位纯数字随机数
	 * @param serviceInterface 接口名称：简写
	 * @return
	 */
	private String getReqResult(String reqJson, int length, String serviceInterface) throws Exception{
		String reqResult = null;
		//BASE64(app_id)
		String appId = UtilBase64.encode(PropertiesUtil.getInstance().getValue("app_id").getBytes());
		//AES密钥
		String aesKey = PropertiesUtil.getInstance().getValue("client_aes_key");
		//平台RSA公钥
		String platform_rsa_publickey = PropertiesUtil.getInstance().getValue("platform_rsa_publickey");
		//BASE64(账户平台公钥加密(加密密钥))
		String passWord = UtilBase64.encode(UtilRsa.encryptByPublicKey(aesKey.getBytes(), platform_rsa_publickey));
		//BASE64(AES(报文体))
		String aesD = UtilAes.AES_Encrypt(aesKey, reqJson);
		//RSA私钥
		String client_rsa_privatekey = PropertiesUtil.getInstance().getValue("client_rsa_privatekey");
		//BASE64(商户RSA私钥采用SHA1withRSA签名(报文体))
		String sign = UtilRsa.sign(reqJson.getBytes(), client_rsa_privatekey);
		//纯数字的随机数
		String random = RandomCharData.createData(length);
		//拼接报文格式
		String up = appId + "|" + passWord + "|" + aesD + "|" + sign + "|" + random;
		//获取易通金服请求基本地址（先使用测试地址）
		String base_url = PropertiesUtil.getInstance().getValue("cs_base_url");
		//使用HttpURLConnection请求服务，并返回信息
		reqResult = HttpUtils.sendPost(base_url + serviceInterface, up);
		return reqResult;
	}
}
